﻿using common.libs;
using common.libs.extends;
using common.server;
using common.server.model;
using common.socks5;
using System;
using System.Threading.Tasks;

namespace common.socks5
{
    public class Socks5MessengerSender
    {
        private readonly MessengerSender messengerSender;
        public Socks5MessengerSender(MessengerSender messengerSender)
        {
            this.messengerSender = messengerSender;
        }

        public async Task<Socks5EnumAuthType> Request(Socks5Info data, IConnection connection)
        {
            var resp = await messengerSender.SendReply(new MessageRequestParamsInfo<byte[]>
            {
                Path = "socks5/request",
                Connection = connection,
                Data = data.ToBytes()
            }).ConfigureAwait(false);
            if (resp.Code == MessageResponeCodes.OK)
            {
                return (Socks5EnumAuthType)resp.Data.Span[0];
            }
            return Socks5EnumAuthType.NotSupported;
        }

        public async Task<Socks5EnumAuthState> Auth(Socks5Info data, IConnection connection)
        {
            var resp = await messengerSender.SendReply(new MessageRequestParamsInfo<byte[]>
            {
                Path = "socks5/auth",
                Connection = connection,
                Data = data.ToBytes()
            }).ConfigureAwait(false);
            if (resp.Code == MessageResponeCodes.OK)
            {
                return (Socks5EnumAuthState)resp.Data.Span[0];
            }
            return Socks5EnumAuthState.UnKnow;
        }

        public async Task<Socks5EnumResponseCommand> Command(Socks5Info data, IConnection connection)
        {
            var resp = await messengerSender.SendReply(new MessageRequestParamsInfo<byte[]>
            {
                Path = "socks5/command",
                Connection = connection,
                Data = data.ToBytes()
            }).ConfigureAwait(false);
            if (resp.Code == MessageResponeCodes.OK)
            {
                return (Socks5EnumResponseCommand)resp.Data.Span[0];
            }
            return Socks5EnumResponseCommand.ServerError;
        }

        public async Task Forward(Socks5Info data, IConnection connection)
        {
            await messengerSender.SendOnly(new MessageRequestParamsInfo<byte[]>
            {
                Path = "socks5/forward",
                Connection = connection,
                Data = data.ToBytes()
            }).ConfigureAwait(false);
        }

        public async Task Response(Socks5Info data, IConnection connection)
        {
            await messengerSender.SendOnly(new MessageRequestParamsInfo<byte[]>
            {
                Path = "socks5/response",
                Connection = connection,
                Data = data.ToBytes()
            }).ConfigureAwait(false);
        }

        public async Task ResponseClose(ulong id, IConnection connection)
        {
            await Response(new Socks5Info { Id = id, Data = Helper.EmptyArray }, connection);
        }
        public async Task RequestClose(ulong id, IConnection connection)
        {
            await Forward(new Socks5Info { Id = id, Data = Helper.EmptyArray },connection);
        }
    }
}
